#include "bsp_ds1302.h"
 
time_data_t TimeData;
uint8_t read_time[7];

static void delay_us(uint32_t time)
{
  time *= 10;
	while(time)
		time--;
}

void ds1302_DATAOUT_init(void)//配置双向I/O端口为输出态
{
  	GPIO_InitTypeDef GPIO_InitStruct = {0};

	GPIO_InitStruct.Pin = GPIO_PIN_0;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
	 
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET);
}
 
void ds1302_DATAINPUT_init(void)//配置双向I/O端口为输入态
{
  	GPIO_InitTypeDef GPIO_InitStruct = {0};

	GPIO_InitStruct.Pin = GPIO_PIN_0;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
 
 
void ds1302_write_onebyte(uint8_t data)//向DS1302发送一字节数据
{
	ds1302_DATAOUT_init();
	uint8_t count=0;
	SCLK_L;
	for(count=0;count<8;count++)
	{	SCLK_L;
		if(data&0x01)
		{DATA_H;}
		else{DATA_L;}//先准备好数据再发送
		SCLK_H;//拉高时钟线，发送数据
		data>>=1;
	}
}
 
void ds1302_wirte_rig(uint8_t address,uint8_t data)//向指定寄存器地址发送数据
{
	uint8_t temp1=address;
	uint8_t temp2=data;
	CE_L;SCLK_L;delay_us(1);
	CE_H;delay_us(2);
	ds1302_write_onebyte(temp1);
	ds1302_write_onebyte(temp2);
	CE_L;SCLK_L;delay_us(2);
}
 
uint8_t ds1302_read_rig(uint8_t address)//从指定地址读取一字节数据
{
	uint8_t temp3=address;
	uint8_t count=0;
	uint8_t return_data=0x00;
	CE_L;SCLK_L;delay_us(3);
	CE_H;delay_us(3);
	ds1302_write_onebyte(temp3);
	ds1302_DATAINPUT_init();//配置I/O口为输入
	delay_us(2);
	for(count=0;count<8;count++)
	{
		delay_us(2);//使电平持续一段时间
		return_data>>=1;
		SCLK_H;delay_us(4);//使高电平持续一段时间
		SCLK_L;delay_us(14);//延时14us后再去读取电压，更加准确
		if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_0))
		{return_data=return_data|0x80;}
	}
	delay_us(2);
	CE_L;DATA_L;
	return return_data;
}
 
void ds1302_init(void)
{
	ds1302_wirte_rig(0x8e,0x00);//关闭写保护
	ds1302_wirte_rig(0x80,0x37);//seconds37秒
	ds1302_wirte_rig(0x82,0x58);//minutes58分
	ds1302_wirte_rig(0x84,0x23);//hours23时
	ds1302_wirte_rig(0x86,0x30);//date30日
	ds1302_wirte_rig(0x88,0x09);//months9月
	ds1302_wirte_rig(0x8a,0x07);//days星期日
	ds1302_wirte_rig(0x8c,0x20);//year2020年
	ds1302_wirte_rig(0x8e,0x80);//关闭写保护
}
 
void ds1302_set(time_data_t *pt)
{
	
	uint16_t year = pt->year-2000;
	
	ds1302_wirte_rig(0x8e,0x00);//关闭写保护
	ds1302_wirte_rig(0x80,(((pt->second/10)<<4)+(pt->second%10)));//seconds37秒
	ds1302_wirte_rig(0x82,(((pt->minute/10)<<4)+(pt->minute%10)));//minutes58分
	ds1302_wirte_rig(0x84,(((pt->hour/10)<<4)+(pt->hour%10)));//hours23时
	ds1302_wirte_rig(0x86,(((pt->day/10)<<4)+(pt->day%10)));//date30日
	ds1302_wirte_rig(0x88,(((pt->month/10)<<4)+(pt->month%10)));//months9月
	ds1302_wirte_rig(0x8a,0x07);//days星期日
	ds1302_wirte_rig(0x8c,(((year/10)<<4)+(year%10)));//year2020年
	ds1302_wirte_rig(0x8e,0x80);//关闭写保护
}
 
void ds1302_read_time(void)
{
	read_time[0]=ds1302_read_rig(0x81);//读秒
	read_time[1]=ds1302_read_rig(0x83);//读分
	read_time[2]=ds1302_read_rig(0x85);//读时
	read_time[3]=ds1302_read_rig(0x87);//读日
	read_time[4]=ds1302_read_rig(0x89);//读月
	read_time[5]=ds1302_read_rig(0x8B);//读星期
	read_time[6]=ds1302_read_rig(0x8D);//读年
}
 
void ds1302_read_realTime(void)
{
	ds1302_read_time();  //BCD码转换为10进制
	if(read_time[0]&0X80)
	{
		ds1302_set(&TimeData);
		return;
	}
	TimeData.second=(read_time[0]>>4)*10+(read_time[0]&0x0f);
	TimeData.minute=((read_time[1]>>4)&(0x07))*10+(read_time[1]&0x0f);
	TimeData.hour=((read_time[2]>>4)*10+(read_time[2]&0x0f));
	TimeData.day=(read_time[3]>>4)*10+(read_time[3]&0x0f);
	TimeData.month=(read_time[4]>>4)*10+(read_time[4]&0x0f);
	TimeData.week=read_time[5];
	TimeData.year=(read_time[6]>>4)*10+(read_time[6]&0x0f)+2000;
}
